﻿using CarPCBATest.Procedure;
using Common;
using ControlzEx;
using Device;
using MahApps.Metro.Controls;
using MahApps.Metro.Controls.Dialogs;
using MahApps.Metro.Converters;
using NewDevice;
using NewDevice.RS232;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Hosting;
using System.Windows;
using System.Windows.Markup.Localizer;
using VM.Core;
using VM.PlatformSDKCS;
using VMControls.Interface;
using VMControls.WPF.Release;
using WebServiceTool.WebReference1;
using static GerberLibrary.ArtWork.Functions.FlowerThing;
using DM3058E = Device.DM3058E;

namespace CarPCBATest.ViewModel
{
    public partial class HomeViewModel : NotifyBase
    {
        private List<(string, int)> SnVerify = new()
        {
            ("P00212066",0),
            ("P00212070",1),
            ("P00212070",2),
            ("P00212075",3),
            ("P00212065",0),
            ("P00212069",1),
            ("P00212069",2),
            ("P00212073",3),
        };

        private List<int> GetNumbersForCode(string code)
        {
            return SnVerify
                .Where(item => item.Item1 == code)
                .Select(item => item.Item2)
                .ToList();
        }

        public ObservableCollection<bool> DOStatus1 { get; set; }
        public ObservableCollection<bool> DIStatus1 { get; set; }
        private bool refresh = false;
        private static bool connected = false;
        public Action SNInputFocusAction;

        private bool vmPorjLoaded = false;
        public List<TestResultData> TestResultDatas { get; set; }
        public List<string> LocalLogs { get; set; }

        public STD_IN STD_IN { get; set; } = new STD_IN();
        public StarnetService WebClient { get; set; } = new StarnetService();

        private void ShowMessage(string msg, string msgType = "错误")
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                var mwin = Application.Current.MainWindow as MetroWindow;

                mwin.ShowMessageAsync(msgType, msg);
            });
        }

        private bool? _testResult;

        public bool? TestResult
        {
            get { return _testResult; }
            set
            {
                _testResult = value;
                this.DoNotify();
            }
        }

        public HomeViewModel()
        {
            ResetCountCommand = new CommandBase(ResetCount);
            StartCommand = new CommandBase(Start);
            ResetCommand = new CommandBase(Reset);
            LoadedCommand = new CommandBase(Loaded);
            UnloadedCommand = new CommandBase(Unloaded);
            TestResult = null;

            SNs = new ObservableCollection<string>();
            SNUploadMesResult = new ObservableCollection<bool?>();
            for (int i = 0; i < 4; i++)
            {
                SNs.Add("");
                SNUploadMesResult.Add(null);
            }

            VmSolution.OnWorkStatusEvent += VmSolution_OnWorkStatusEvent;//工作执行状态回调
            VmSolution.OnSolutionLoadEndEvent += VmSolution_OnSolutionLoadEndEvent;
            VmSolution.OnSolutionLoadBeginEvent += VmSolution_OnSolutionLoadBeginEvent;
        }

        private void ResetCount(object obj)
        {
            CameraTool.Open();
            OKCount = 0;
            NGCount = 0;
        }

        private void VmSolution_OnSolutionLoadBeginEvent(ImvsSdkDefine.IMVS_SOLUTION_LOAD_BEGEIN_INFO solutionLoadBeginInfo)
        {
            vmPorjLoaded = false;
        }

        private void VmSolution_OnSolutionLoadEndEvent(ImvsSdkDefine.IMVS_SOLUTION_LOAD_END_INFO solutionLoadEndInfo)
        {
            try
            {
                VmSolution.Instance.SilentExecute();
            }
            catch (VmException vex)
            {
                Mylog.Error(vex, vex.Message);
                Log = vex.Message;
            }
            vmPorjLoaded = true;
        }

        private void StartAction()
        {
            Start(null);
        }

        private PcbConfig _pcbConfig;

        public PcbConfig PcbConfig
        {
            get { return _pcbConfig; }
            set
            {
                if (value != null)
                {
                    VisionProjPath = value.VisionProjPath;
                }
                _pcbConfig = value;
                this.DoNotify();
            }
        }

        private string _visionProjPath;

        public string VisionProjPath
        {
            get { return _visionProjPath; }
            set
            {
                if (value != _visionProjPath & value != null)
                {
                    Log = $"加载视觉方案";
                    if (File.Exists(value))
                    {
                        Task.Run(() =>
                        {
                            try
                            {
                                VisionTool.LoadVMSolution(value);
                                Log = "加载视觉方案成功";
                                vmPorjLoaded = true;
                            }
                            catch (Exception ex)
                            {
                                Log = ex.Message;
                            }
                        });
                    }
                    else
                    {
                        Log = $"视觉方案不存在[{value}]";
                    }
                }
                _visionProjPath = value;
                this.DoNotify();
            }
        }

        private void InitDevice()
        {
            var dm3058e = new NewDevice.RS232.DM3058E();
            dm3058e.Connect(PcbConfigHelper.Load().DM3025EPort, 9600);
            dm3058e.SetFunction(NewDevice.RS232.Function.DCI);
            Global.DM3058E = dm3058e;

            IT6302 iT6302 = new IT6302();
            iT6302.Connect(PcbConfigHelper.Load().IT6302APort, 9600);
            iT6302.SetRemote();
            Global.IT6302 = iT6302;

            Global.CANfd = new S12L_LedA();
            Global.CANfd.Init();

            Global.ZhiContrl = new ZhiContrl();
            Global.ZhiContrl.Connect(PcbConfigHelper.Load().zhiConPort, 38400);

            var io = new IOModule();
            io.Connect(PcbConfigHelper.Load().IOModule1IP);
            io.IOModuleType = IOModuleType.All;
            Global.IOModule1 = io;
        }

        private void Loaded(object obj)
        {
            try
            {
                var config = PcbConfigHelper.AllPcbConfig;
                PcbConfig = config.ListConfig.Where(t => t.No == config.UsingNo).ToList()[0];

                snLength = PcbConfig.SNLength;
                if (config is not null)
                {
                    WebClient.Url = config.WebServiceUrl;
                }

                if (connected == false)
                {
                    try
                    {
                        InitDevice();
                    }
                    catch (Exception ex)
                    {
                        Log = ex.Message;
                    }

                    connected = true;
                }

                Global.CANfd.StopSendCmd();

                this.SNInputFocusAction.Invoke();
                //监听IO
                DIStatus1 = new ObservableCollection<bool>();
                DOStatus1 = new ObservableCollection<bool>();
                refresh = true;
                for (int i = 0; i < 12; i++)
                {
                    DIStatus1.Add(false);
                    DOStatus1.Add(false);
                }
                refresh = false;
                DIStatus1.CollectionChanged += DIStatus_CollectionChanged1;
                DOStatus1.CollectionChanged += DOStatus_CollectionChanged1;
                Task.Run(() =>
                {
                    Thread.Sleep(1000);
                    while (true)
                    {
                        try
                        {
                            refresh = true;
                            for (int i = 0; i < 12; i++)
                            {
                                if (Global.IOModule1 is not null)
                                {
                                    DIStatus1[i] = Global.IOModule1.GetDIValue(i);
                                    DOStatus1[i] = Global.IOModule1.GetDOValue(i);
                                }
                            }

                            refresh = false;
                            Thread.Sleep(100);
                        }
                        catch (Exception ex)
                        {
                            Log = ex.Message;
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                Log = ex.Message;
            }
        }

        private void DIStatus_CollectionChanged1(object sender, NotifyCollectionChangedEventArgs e)
        {
            int channelValue = (int)e.NewStartingIndex;
            var tempStart = Global.IOModule1.GetDIValue((int)DIDefine.Start);
            emgStop = !Global.IOModule1.GetDIValue((int)DIDefine.EmgStop);
            //safeLight = !Global.IOModule1.GetDIValue((int)DIDefine.SafeLight);
            if (tempStart)
            {
                StartAction();
            }
        }

        private bool emgStop;
        private bool safeLight = false;

        private void DOStatus_CollectionChanged1(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (!refresh)
            {
                int index = e.NewStartingIndex;
                int value = (sender as ObservableCollection<bool>)[index] ? 1 : 0;
                Global.IOModule1.SetDOValue(index, value);
            }
        }

        private void Unloaded(object obj)
        {
        }

        public void InitDO()
        {
            Global.IOModule1.SetDOValue((int)DODefine.Power1, 0);
            Global.IOModule1.SetDOValue((int)DODefine.Power2, 0);
            Global.IOModule1.SetDOValue((int)DODefine.Power3, 0);
            Global.IOModule1.SetDOValue((int)DODefine.BurnIO, 0);
            Global.IOModule1.SetDOValue((int)DODefine.InProgram, 0);
            Global.IOModule1.SetDOValue((int)DODefine.CanfdCom, 0);
            Log = "关闭所有IO信号";
        }

        /// <summary>
        /// JLINK烧录
        /// </summary>
        public bool BrunProgram()
        {
            string filePath = PcbConfigHelper.Load().JlinkSL;

            string exePath = PcbConfigHelper.Load().JlinkEXE;
            return Jlink.WriteJflash(filePath, exePath);
        }

        private void Reset(object obj)
        {
            try
            {
                if (Global.IsBusy == true)
                {
                    Log = "正在执行其它操作";
                    return;
                }

                Global.IsBusy = true;
                InitDO();
                TestResult = null;

                SetColorLamp(1);
                Global.IOModule1.SetDOValue((int)DODefine.AirReset, 0);

                for (int i = 0; i < SNUploadMesResult.Count; i++)
                {
                    SNUploadMesResult[i] = null;
                    SNs[i] = "";
                }

                this.SNInputFocusAction.Invoke();
                Global.IsBusy = false;
            }
            catch (Exception ex)
            {
                Log = ex.Message + "!";
                Global.IsBusy = false;
                Log = ex.Message;
            }
        }

        #region valueFieldName

        public ObservableCollection<bool?> SNUploadMesResult { get; set; } = new ObservableCollection<bool?>();
        public ObservableCollection<string> SNs { get; set; }

        private string _sn;

        public string SN
        {
            get { return _sn; }
            set
            {
                _sn = value;

                this.DoNotify();
                if (snLength > 9 && SN.Length == snLength)
                {
                    var snPos = GetNumbersForCode(_sn.Substring(0, 9));
                    if (snPos.Count == 0)
                    {
                        Log = $"零件号未收录[{_sn}]";
                    }
                    else if (snPos.Count == 1)
                    {
                        SNs[snPos[0]] = _sn;
                        SNInputFocusAction.Invoke();
                    }
                    else if (snPos.Count == 2)
                    {
                        if (SNs[snPos[0]].Length == snLength)
                        {
                            if (_sn == SNs[snPos[0]])
                            {
                            }
                            else
                            {
                                SNs[snPos[1]] = _sn;
                            }
                            SNInputFocusAction.Invoke();
                        }
                        else
                        {
                            SNs[snPos[0]] = _sn;
                            SNInputFocusAction.Invoke();
                        }
                    }
                    SN = "";
                }
            }
        }

        private int _okCount;

        public int OKCount
        {
            get { return _okCount; }
            set
            {
                _okCount = value;
                if (NGCount + value > 0)
                {
                    OKRate = Math.Round(100 * (OKCount) / ((double)(NGCount + value)), 2).ToString() + "%";
                }
                else
                {
                    OKRate = "";
                }
                this.DoNotify();
            }
        }

        private int _ngCount;

        public int NGCount
        {
            get { return _ngCount; }
            set
            {
                _ngCount = value;
                if (OKCount + value > 0)
                {
                    OKRate = Math.Round(100 * (OKCount) / ((double)(OKCount + value)), 2).ToString() + "%";
                }
                else
                {
                    OKRate = "";
                }
                this.DoNotify();
            }
        }

        private string _okRate;

        public string OKRate
        {
            get { return _okRate; }
            set
            {
                _okRate = value;
                this.DoNotify();
            }
        }

        #endregion valueFieldName

        private int count = 0;

        /// <summary>
        /// 0 绿灯
        /// 1 黄灯
        /// -1 红灯
        /// </summary>
        /// <param name="status"></param>
        private void SetColorLamp(int status)
        {
            if (status == 0)
            {
                isNg = false;
                Thread.Sleep(100);
                Global.IOModule1.SetDOValue((int)DODefine.GreenLight, 1);
                Global.IOModule1.SetDOValue((int)DODefine.YellowLight, 0);
                Global.IOModule1.SetDOValue((int)DODefine.RedLight, 0);
            }
            else if (1 == status)
            {
                isNg = false;
                Thread.Sleep(100);
                Global.IOModule1.SetDOValue((int)DODefine.GreenLight, 0);
                Global.IOModule1.SetDOValue((int)DODefine.YellowLight, 1);
                Global.IOModule1.SetDOValue((int)DODefine.RedLight, 0);
            }
            else if (-1 == status)
            {
                Global.IOModule1.SetDOValue((int)DODefine.GreenLight, 0);
                Global.IOModule1.SetDOValue((int)DODefine.YellowLight, 0);
                Global.IOModule1.SetDOValue((int)DODefine.RedLight, 0);
                isNg = true;
                Task.Run(() =>
                {
                    while (true)
                    {
                        for (int i = 0; i < 100; i++)
                        {
                            if (!isNg)
                            {
                                return;
                            }
                            Thread.Sleep(10);
                        }
                        Global.IOModule1.SetDOValue((int)DODefine.RedLight, 0);
                        for (int i = 0; i < 60; i++)
                        {
                            if (!isNg)
                            {
                                return;
                            }
                            Thread.Sleep(10);
                        }
                        Global.IOModule1.SetDOValue((int)DODefine.RedLight, 1);
                    }
                });
            }
        }

        private bool isRunnging = false;

        private void Start(object obj)
        {
            if (isRunnging)
            {
                return;
            }

            if (Global.IsBusy == true)
            {
                Log = "正在执行其它操作";
                return;
            }

            Global.IsBusy = true;
            Task.Run(() =>
            {
                isRunnging = true;
                try
                {
                    TestResult = null;

                    for (int i = 0; i < SNUploadMesResult.Count; i++)
                    {
                        SNUploadMesResult[i] = null;
                    }

                    Log = "--------------------" + count++.ToString();
                    if (PcbConfig is null)
                    {
                        throw new Exception("测试方案不能为空");
                    }
                    int stationCount = PcbConfig.ListLedCurrentConfig[0].StationCount;
                    snLength = PcbConfig.SNLength;
                    string ctlStyle = PcbConfig.CtlStyle;

                    #region 参数校验

                    // 探针使用次数校验
                    if (PcbConfig.ProbeMaxUsedTimes < PcbConfig.ProbeUsedTimes)
                    {
                        throw new Exception("探针使用次数超过预设值");
                    }

                    #endregion 参数校验

                    if (!vmPorjLoaded)
                    {
                        throw new Exception("请等待视觉方案加载完成");
                    }

                    #region SN校验

                    for (int i = 0; i < SNs.Count; i++)
                    {
                        if (SNs[i].Length != snLength)
                        {
                            throw new Exception("SN长度异常");
                        }
                    }
                    if (SNs.Count != SNs.Distinct().Count())
                    {
                        throw new Exception("SN包含重复元素");
                    }

                    #endregion SN校验

                    TestResultDatas = new List<TestResultData>();
                    for (int i = 0; i < 4; i++)
                    {
                        var retData = new TestResultData();
                        retData.IsOK = true;
                        retData.SN = SNs[i];
                        TestResultDatas.Add(retData);
                    }

                    #region IO 初始化

                    SetColorLamp(1);

                    #endregion IO 初始化

                    InitDO();

                    Log = "电源OFF";

                    {
                        //1 气缸下压
                        Global.IOModule1.SetDOValue((int)DODefine.AirReset, 1);
                        bool timeOut1 = false;
                        // 等待气缸到位
                        Task.Run(() =>
                        {
                            Thread.Sleep(15000);
                            timeOut1 = true;
                        });
                        while (true)
                        {
                            if (Global.IOModule1.GetDIValue((int)DIDefine.AirWork))
                            {
                                break;
                            }
                            if (timeOut1)
                            {
                                break;
                            }
                            if (emgStop)
                            {
                                throw new Exception("急停触发");
                            }
                            if (safeLight)
                            {
                                throw new Exception("安全光栅触发");
                            }
                            Thread.Sleep(100);
                        }
                        if (timeOut1)
                        {
                            throw new Exception("等待气缸到位超时");
                        }
                        Log = "气缸到位";
                    }
                    Log = "开始测试开断路";

                    var result2 = Global.ZhiContrl.Test();
                    TestResultDatas[0].IsOK = result2;
                    TestResultDatas[0].NgMsg.Add("开断路" + (result2 ? "OK" : "NG"));
                    if (!result2)
                    {
                        throw new Exception("开短路测试NG");
                    }

                    Global.IT6302.SetCurrent(2, 2, 2);
                    Global.IT6302.SetVoltage(14, 14, 14);
                    Global.IT6302.SetOutputStatus(true);
                    Thread.Sleep(300);
                    Global.IOModule1.SetDOValue((int)DODefine.Power1, 1);
                    Global.IOModule1.SetDOValue((int)DODefine.Power2, 1);

                    // 更新探针使用次数
                    PcbConfig.ProbeUsedTimes += 1;
                    PcbConfigHelper.AllPcbConfig.ListConfig.Where(x => x.No == PcbConfig.No).ToArray()[0].ProbeUsedTimes = PcbConfig.ProbeUsedTimes;
                    PcbConfigHelper.Save();

                    Log = "开始烧录";

                    Global.IOModule1.SetDOValue((int)DODefine.BurnIO, 1);
                    Thread.Sleep(100);
                    bool sts = BrunProgram();
                    if (!sts)
                    {
                        throw new Exception("MCU烧录失败!");
                    }
                    else
                    {
                        Log = "MCU烧录成功";
                    }
                    // 切换烧录模式
                    if (PcbConfig.BurnConfig.SubBurnConfigs.Where(x => x.IsBurn == true).Count() > 0)   //需要芯片烧录
                    {
                        //// 2 打开电源
                        Global.IT6302.SetCurrent(2, 2, 2);
                        Global.IT6302.SetVoltage(8, 8, 5);
                        Global.IT6302.SetOutputStatus(true);
                        Thread.Sleep(300);
                        Global.IOModule1.SetDOValue((int)DODefine.Power1, 0);
                        Global.IOModule1.SetDOValue((int)DODefine.Power2, 0);
                        Log = "电源ON";
                        Thread.Sleep(100);
                        Global.IOModule1.SetDOValue((int)DODefine.InProgram, 1);
                        Log = "切换烧录模式";
                        Thread.Sleep(500);

                        // 3烧录
                        if (PcbConfig.BurnConfig.SubBurnConfigs != null)
                        {
                            if (PcbConfig.ChipType == "NSL21912")   //NSL21912 芯片烧录
                            {
                                foreach (var item in PcbConfig.BurnConfig.SubBurnConfigs)
                                {
                                    if (!item.IsBurn)
                                        continue;

                                    string checkCode = "";

                                    int newAddress = 0x00;
                                    bool ret = NSL21916.WriteFlash(PcbConfig.BurnConfig.Port, item.BrunFilePath, item.McuAddress, out newAddress);
                                    if (ret)
                                    {
                                        Log = $"芯片地址[{item.McuAddress}]烧录完成";
                                        //LocalLogs.Add(Log);
                                    }
                                    else
                                    {
                                        foreach (var err in NSL21916.listErr)
                                        {
                                            Log = err;
                                        }
                                        Log = $"芯片地址[{item.McuAddress}]烧录失败";
                                        NGCount++;
                                        throw new Exception("测试失败");
                                    }
                                    Thread.Sleep(1000);
                                    Log = "开始校验";
                                    bool ret2 = NSL21916.ReadFlash(PcbConfig.BurnConfig.Port, item.BrunFilePath, newAddress, out checkCode);

                                    Log = $"芯片校验码为:{checkCode}";
                                    //LocalLogs.Add(Log);
                                    if (ret2)
                                    {
                                        Log = $"芯片地址[{item.McuAddress}]校验成功";
                                        //LocalLogs.Add(Log);
                                    }
                                    else
                                    {
                                        foreach (var err in NSL21916.listErr)
                                        {
                                            Log = err;
                                        }
                                        Log = $"芯片地址[{item.McuAddress}]校验失败";
                                        NGCount++;
                                        throw new Exception("测试失败");
                                    }
                                }
                            }
                        }
                        ///
                        //// 切换测试模式
                        Global.IOModule1.SetDOValue((int)DODefine.InProgram, 0);
                        Log = "电源OFF";
                    }

                    Global.IT6302.SetVoltage(14, 14, 5);
                    Global.IT6302.SetCurrent(2, 2, 2);
                    Global.IT6302.SetOutputStatus(true);

                    Global.IOModule1.SetDOValue((int)DODefine.Power1, 1);
                    Global.IOModule1.SetDOValue((int)DODefine.Power2, 0);

                    Thread.Sleep(300);
                    Log = "休眠电流测试";

                    Thread.Sleep(10000);
                    double stopVoltage = Global.DM3058E.GetValue() * 1000000;
                    double StopVoltage = Math.Round(stopVoltage, 3);

                    if (StopVoltage < 250)
                    {
                        TestResultDatas[0].NgMsg.Add($"休眠电流：[{StopVoltage}uA] OK");
                        Log = $"休眠电流OK：{StopVoltage}uA";
                    }
                    else
                    {
                        TestResultDatas[0].IsOK = false;
                        TestResultDatas[0].NgMsg.Add($"休眠电流：[{StopVoltage}uA] NG");
                        Log = $"休眠电流NG：{StopVoltage}uA";
                    }
                    Log = "电源OFF";
                    Global.IOModule1.SetDOValue((int)DODefine.Power1, 0);
                    Thread.Sleep(200);

                    Global.IOModule1.SetDOValue((int)DODefine.Power1, 1);
                    Global.IOModule1.SetDOValue((int)DODefine.Power2, 1);

                    Log = "电源ON";
                    Thread.Sleep(1200);

                    // 4视觉测试
                    bool result = true;

                    if (PcbConfig.ListLedCurrentConfig is not null)
                    {
                        Global.CANfd.StartSendCmd();
                        Thread.Sleep(1000);
                        //int canNum = Global.CANfd.canResultCount(0x276);
                        //LocalLogs.Add($"工位1SN={SN1}");
                        foreach (var item in PcbConfig.ListLedCurrentConfig)
                        {
                            currentProcName = item.ProcName;
                            Type classType = typeof(HomeViewModel);
                            MethodInfo methodInfo = classType.GetMethod(item.TestMethodName);
                            if (methodInfo == null)
                            {
                                throw new Exception($"测试方法未找到[{item.TestMethodName}]");
                            }
                            bool ret = (bool)methodInfo.Invoke(this, new object[] { item });
                            if (!ret)
                            {
                                result = false;
                            }
                        }

                        int count = Global.CANfd.ReadReceivedQueue(out uint id, out byte[] data);
                        if (count > 0)
                        {
                            TestResultDatas[0].NgMsg.Add($"canfd收到{count}条数据,id=[0x{id.ToString("X")}],data={BitConverter.ToString(data).Replace("-", " ")}");
                        }
                        else
                        {
                            TestResultDatas[0].NgMsg.Add("canfd未收到数据");
                        }

                        if (result)
                        {
                            OKCount++;
                            Log = "测试OK";
                            TestResult = true;
                            SetColorLamp(0);
                        }
                        else
                        {
                            NGCount++;
                            SetColorLamp(-1);
                            Log = "测试NG";
                            TestResult = false;
                        }
                    }

                    // 发送测试日志到MES
                    if (PcbConfigHelper.AllPcbConfig.UploadMes)
                    {
                        try
                        {
                            int snIndex = 0;

                            Type classType = typeof(HomeViewModel);
                            foreach (var item in TestResultDatas)
                            {
                                STD_IN.Update(item.SN, PcbConfigHelper.AllPcbConfig.Station, "", result, result ? "测试OK" : "测试NG", item.NgMsg.ToArray());
                                string inputXml = STD_IN.GenerateStringXml();
                                string outputXml = WebClient.DataService(PcbConfigHelper.AllPcbConfig.CallMethodName, inputXml);
                                var retData = STD_IN.ParseReturnXml(outputXml);
                                if (retData.Item1 == "0")   //调用webservice成功
                                {
                                    SNUploadMesResult[snIndex] = true;
                                    Log = $"工位[{snIndex + 1}]上传MES成功";
                                }
                                else
                                {
                                    SNUploadMesResult[snIndex] = false;
                                    Log = $"工位[{snIndex + 1}]上传MES失败：" + retData.Item2;
                                }
                                snIndex++;
                            }
                        }
                        catch (Exception ex)
                        {
                            Log = "Web Service 调用异常：" + ex.Message;
                            Mylog.Error(ex, ex.Message);
                        }
                    }

                    Log = "电源OFF";
                    //Thread.Sleep(1200);
                    InitDO();
                    Log = "气缸复位";

                    Thread.Sleep(100);

                    // 记录本地日志
                    {
                        string directory = Environment.CurrentDirectory + $"\\Data\\{DateTime.Now.ToString("yyyMMdd")}";
                        if (!Directory.Exists(directory))
                        {
                            Directory.CreateDirectory(directory);
                        }

                        foreach (var item in TestResultDatas)
                        {
                            string ret = item.IsOK ? "OK" : "NG";
                            string file = $"{directory}\\{item.SN}_{ret}_{DateTime.Now.ToString("yyyMMddHHmmss")}.txt";
                            using (StreamWriter writer = new StreamWriter(file))
                            {
                                foreach (var msg in item.NgMsg)
                                {
                                    writer.WriteLine(msg);
                                }
                            }
                        }
                    }

                    CameraTool.Close();
                }
                catch (Exception ex)
                {
                    CameraTool.Close();
                    Log = ex.Message;
                    TestResult = false;
                    Mylog.Error(ex, ex.Message);
                    SetColorLamp(-1);
                }
                finally
                {
                    Global.IOModule1.SetDOValue((int)DODefine.AirReset, 0);
                    InitDO();
                    for (int i = 0; i < 4; i++)
                    {
                        SNs[i] = "";
                    }
                    Global.CANfd.StopSendCmd();
                    this.SNInputFocusAction.Invoke();
                    isRunnging = false;
                    Global.IsBusy = false;
                }
            });
        }

        private string currentProcName;
        public CommandBase StartCommand { get; set; }
        public CommandBase ResetCommand { get; set; }
        public CommandBase UnloadedCommand { get; set; }
        public CommandBase LoadedCommand { get; set; }

        public CommandBase ResetCountCommand { get; set; }

        private void VmSolution_OnWorkStatusEvent(ImvsSdkDefine.IMVS_MODULE_WORK_STAUS workStatusInfo)
        {
            try
            {
                Mylog.Info($"procid[{workStatusInfo.nProcessID}],status[{workStatusInfo.nWorkStatus}]");
                if (workStatusInfo.nWorkStatus == 0 && workStatusInfo.nProcessID == currentProcId)//为0表示执行完毕，为1表示正在执行；10000表示流程1
                {
                    //通过流程获取结果
                    //VmProcedure vmProcess1 = (VmProcedure)VmSolution.Instance[currentProcName];
                    //String radiusResult = vmProcess1.ModuResult.GetOutputFloat("out").pFloatVal[0].ToString();
                    vmResult1 = VisionTool.GetGlobalVar("result1");
                    vmResult2 = VisionTool.GetGlobalVar("result2");
                    vmResult3 = VisionTool.GetGlobalVar("result3");
                    vmResult4 = VisionTool.GetGlobalVar("result4");

                    vmProcHaveExec = true;
                    Console.WriteLine("视觉判断耗时" + swGlobal.ElapsedMilliseconds);
                }
            }
            catch (VmException ex)
            {
                Mylog.Error(ex, ex.Message);
                //ShowMessage(ex.Message);
            }
        }

        private string _log;
        private string vmResult1;
        private string vmResult2;
        private string vmResult3;
        private string vmResult4;
        private bool vmProcHaveExec;
        private bool isNg;
        private int snLength;

        public string Log
        {
            get { return _log; }
            set
            {
                Application.Current.Dispatcher.Invoke(new Action(() =>
                {
                    _log = value;
                    this.DoNotify();
                }));
            }
        }
    }
}